package com.example.lab.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.lab.entity.Role;
import com.example.lab.entity.User;
import com.example.lab.entity.dto.UserCreateDTO;
import com.example.lab.entity.dto.UserUpdateDTO;
import com.example.lab.mapper.RoleMapper;
import com.example.lab.result.Result;
import com.example.lab.service.IUserService;
import com.example.lab.service.impl.UserServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 *@Author: 布莱恩
 *@Date: 2025/6/18 9:54
 *@Description:
 **/
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {

    private final UserServiceImpl userService;
    private final RoleMapper roleMapper;
    private final PasswordEncoder passwordEncoder;

    @PreAuthorize("hasAuthority('user:manage')")
    @GetMapping
    public Result<Page<User>> getUsers(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        Page<User> userPage = userService.page(new Page<>(page, size));
        return Result.success(userPage);
    }

    @PreAuthorize("hasAuthority('user:manage')")
    @GetMapping("/{id}")
    public Result<User> getUserDetail(@PathVariable Integer id) {
        User user = userService.getById(id);
        if (user == null) {
            return Result.fail(404, "用户不存在");
        }

        List<Role> roles = userService.getUserRoles(id);
        user.setRoles(roles);

        return Result.success(user);
    }

    @PreAuthorize("hasAuthority('user:create')")
    @PostMapping
    public Result<?> createUser(@RequestBody @Valid UserCreateDTO dto) {
        if (userService.exists(new LambdaQueryWrapper<User>().eq(User::getUsername, dto.getUsername()))) {
            return Result.fail("用户名已存在");
        }

        User user = new User();
        BeanUtils.copyProperties(dto, user);
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        user.setStatus(true);

        boolean saved = userService.save(user);
        return saved ? Result.success() : Result.fail("创建用户失败");
    }

    @PreAuthorize("hasAuthority('user:edit')")
    @PutMapping("/{id}")
    public Result<?> updateUser(@PathVariable Integer id, @RequestBody @Valid UserUpdateDTO dto) {
        User user = userService.getById(id);
        if (user == null) {
            return Result.fail(404, "用户不存在");
        }

        BeanUtils.copyProperties(dto, user, "password");
        if (StringUtils.isNotBlank(dto.getPassword())) {
            user.setPassword(passwordEncoder.encode(dto.getPassword()));
        }

        boolean updated = userService.updateById(user);
        return updated ? Result.success() : Result.fail("更新用户失败");
    }

    @PreAuthorize("hasAuthority('user:delete')")
    @DeleteMapping("/{id}")
    public Result<?> deleteUser(@PathVariable Integer id) {
        if (!userService.exists(new LambdaQueryWrapper<User>().eq(User::getUserId, id))) {
            return Result.fail(404, "用户不存在");
        }

        userService.removeUserRoles(id);
        boolean deleted = userService.removeById(id);
        return deleted ? Result.success() : Result.fail("删除用户失败");
    }

    @PreAuthorize("hasAuthority('user:manage')")
    @GetMapping("/roles")
    public Result<List<Role>> getAllRoles() {
        List<Role> roles = roleMapper.selectList(null);
        return Result.success(roles);
    }

    @PreAuthorize("hasAuthority('user:manage')")
    @PostMapping("/{userId}/roles")
    public Result<?> assignRoles(@PathVariable Integer userId, @RequestBody List<Integer> roleIds) {
        if (!userService.exists(new LambdaQueryWrapper<User>().eq(User::getUserId, userId))) {
            return Result.fail(404, "用户不存在");
        }

        if (CollectionUtils.isNotEmpty(roleIds)) {
            long validRoles = roleMapper.selectCount(new LambdaQueryWrapper<Role>()
                    .in(Role::getRoleId, roleIds));
            if (validRoles != roleIds.size()) {
                return Result.fail("包含无效的角色ID");
            }
        }

        boolean success = userService.assignRolesToUser(userId, roleIds);
        return success ? Result.success() : Result.fail("分配角色失败");
    }

}
